using System;
using System.Web.UI;
using SharpPieces.Web.Controls;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Configuration;

namespace SharpPieces.DemoApp
{

    /// <summary>
    /// The Database Image demo page.
    /// </summary>
    public partial class DatabaseImage : Page
    {

        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load"></see> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs"></see> 
        /// object that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // register a custom image creator, in this case the type that loads a DB 
            // product image based on the passed product id; very well this registration 
            // can be performed in the row data bound event of a grid

            this.DynamicImage1.RegisterCustomCreatorType<DBProductImageLoader>("productId", "716");

            // suppose we know the price for this product, we can apply a price mark 
            // by registering a custom transformation

            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("oldPrice", "65.00");
            parameters.Add("newPrice", "49.99");

            this.DynamicImage1.RegisterCustomTransformationType<DBProductPriceInformation>(parameters);
        }

    }

    /// <summary>
    /// Represents a DB product image creator.
    /// </summary>
    public class DBProductImageLoader : IImageCreator
    {
        #region IImageCreator Members

        /// <summary>
        /// Creates an image according to the specified params.
        /// </summary>
        /// <param name="parameters">The creator params.</param>
        /// <returns>A new image based on the params.</returns>
        public System.Drawing.Image Get(System.Collections.Specialized.NameValueCollection parameters)
        {
            // this is the method that gets the image from the DB;
            // in other scenarios it can have different implementation
            // so it is the place where the developer loads/creates the image

            // get the id parameter passed to here

            int productId = int.Parse(parameters["productId"]);

            // get the image from DB

            using (SqlConnection conn = new SqlConnection(
                ConfigurationManager.ConnectionStrings["AdventureWorksConnStr"].ConnectionString))
            {
                conn.Open();

                using (SqlCommand comm = new SqlCommand(
                    "select pp.ThumbNailPhoto from Production.Product p " + 
                    "inner join Production.ProductProductPhoto ppp on p.ProductID=ppp.ProductID " +
                    "inner join Production.ProductPhoto pp on ppp.ProductPhotoID=pp.ProductPhotoID " +
                    "where p.ProductID=@productID", conn))
                {
                    comm.Parameters.Add(new SqlParameter("@productId", productId));

                    byte[] buffer = (byte[])comm.ExecuteScalar();

                    using (Bitmap dbImg = new Bitmap(new Bitmap(new MemoryStream(buffer, 0, buffer.Length))))
                    {
                        MemoryStream ms = new MemoryStream();
                        dbImg.Save(ms, ImageFormat.Bmp);
                        return System.Drawing.Image.FromStream(ms);
                    }
                }
            }
        }

        #endregion
    }

    /// <summary>
    /// Represents a image transformation by adding price info.
    /// </summary>
    public class DBProductPriceInformation : IImageTransformation
    {
        #region IImageTransformation Members

        /// <summary>
        /// Applies the specified image transformation.
        /// </summary>
        /// <param name="image">The image to be transfored.</param>
        /// <param name="parameters">The transformation params.</param>
        public void Apply(ref Image image, System.Collections.Specialized.NameValueCollection parameters)
        {
            // this is the method that changes the image according to the custom needs;
            // for instance here is added price information for the product image

            // get the price parameter passed to here

            decimal oldPrice = decimal.Parse(parameters["oldPrice"]);
            decimal newPrice = decimal.Parse(parameters["newPrice"]);

            using (Font fontForOld = (Font)new FontConverter().ConvertFromString("Arial, 4pt, style=Strikeout"))
            using (Font fontForNew = (Font)new FontConverter().ConvertFromString("Arial, 4pt, style=Bold"))
            using (Graphics g = Graphics.FromImage(image))
            {
                // add a nice image border

                using (Pen pen = new Pen(Color.Gray))
                {
                    g.DrawRectangle(pen, new Rectangle(Point.Empty, image.Size - new Size(1, 1)));
                }

                SizeF oldTextSize = g.MeasureString(string.Format("{0}$", oldPrice), fontForOld);
                SizeF newTextSize = g.MeasureString(string.Format("{0}$", newPrice), fontForNew);

                // draw the new price

                g.DrawString(string.Format("{0}$", newPrice), fontForNew, Brushes.Red, 
                    new PointF(image.Width - 5, image.Height - 5) - newTextSize);

                // draw the old price

                g.DrawString(string.Format("{0}$", oldPrice), fontForOld, Brushes.DimGray, 
                    new PointF(image.Width - 5, image.Height - newTextSize.Height - 5) - oldTextSize);
            }
        }

        #endregion
    }

}
